clear_bit(irq, d->arch.pv_domain.pirq_eoi_map);
}
-static void _irq_guest_eoi(struct irq_desc *desc)
-{
- irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
- unsigned int i, irq = desc - irq_desc;
-
- if ( !(desc->status & IRQ_GUEST_EOI_PENDING) )
- return;
-
- for ( i = 0; i < action->nr_guests; ++i )
- clear_pirq_eoi(action->guest[i],
- domain_irq_to_pirq(action->guest[i], irq));
-
- desc->status &= ~(IRQ_INPROGRESS|IRQ_GUEST_EOI_PENDING);
- desc->handler->enable(irq);
-}
-
static void set_eoi_ready(void *data);
static void irq_guest_eoi_timer_fn(void *data)
on_selected_cpus(&cpu_eoi_map, set_eoi_ready, desc, 0);
spin_lock_irq(&desc->lock);
break;
- case ACKTYPE_NONE:
- _irq_guest_eoi(desc);
- break;
}
out:
struct irq_desc *desc = irq_to_desc(irq);
irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
struct domain *d;
- int i, sp, already_pending = 0;
+ int i, sp;
struct pending_eoi *peoi = this_cpu(pending_eoi);
int vector = get_irq_regs()->entry_vector;
if ( (action->ack_type != ACKTYPE_NONE) &&
!test_and_set_bool(pirq->masked) )
action->in_flight++;
- if ( hvm_do_IRQ_dpci(d, pirq) )
- {
- if ( action->ack_type == ACKTYPE_NONE )
- {
- already_pending += !!(desc->status & IRQ_INPROGRESS);
- desc->status |= IRQ_INPROGRESS; /* cleared during hvm eoi */
- }
- }
- else if ( send_guest_pirq(d, pirq) &&
- (action->ack_type == ACKTYPE_NONE) )
- {
- already_pending++;
- }
+ if ( !hvm_do_IRQ_dpci(d, pirq) )
+ send_guest_pirq(d, pirq);
}
- stop_timer(&action->eoi_timer);
-
- if ( (action->ack_type == ACKTYPE_NONE) &&
- (already_pending == action->nr_guests) )
+ if ( action->ack_type != ACKTYPE_NONE )
{
- desc->handler->disable(irq);
- desc->status |= IRQ_GUEST_EOI_PENDING;
- for ( i = 0; i < already_pending; ++i )
- {
- d = action->guest[i];
- set_pirq_eoi(d, domain_irq_to_pirq(d, irq));
- /*
- * Could check here whether the guest unmasked the event by now
- * (or perhaps just re-issue the send_guest_pirq()), and if it
- * can now accept the event,
- * - clear all the pirq_eoi bits we already set,
- * - re-enable the vector, and
- * - skip the timer setup below.
- */
- }
+ stop_timer(&action->eoi_timer);
+ migrate_timer(&action->eoi_timer, smp_processor_id());
+ set_timer(&action->eoi_timer, NOW() + MILLISECS(1));
}
-
- migrate_timer(&action->eoi_timer, smp_processor_id());
- set_timer(&action->eoi_timer, NOW() + MILLISECS(1));
}
/*
action = (irq_guest_action_t *)desc->action;
irq = desc - irq_desc;
- if ( action->ack_type == ACKTYPE_NONE )
- {
- ASSERT(!pirq->masked);
- stop_timer(&action->eoi_timer);
- _irq_guest_eoi(desc);
- }
-
if ( unlikely(!test_and_clear_bool(pirq->masked)) ||
unlikely(--action->in_flight != 0) )
{
spin_lock_irq(&desc->lock);
}
break;
- case ACKTYPE_NONE:
- stop_timer(&action->eoi_timer);
- _irq_guest_eoi(desc);
- break;
}
/*
BUG_ON(!cpus_empty(action->cpu_eoi_map));
desc->action = NULL;
- desc->status &= ~(IRQ_GUEST|IRQ_GUEST_EOI_PENDING|IRQ_INPROGRESS);
+ desc->status &= ~(IRQ_GUEST|IRQ_INPROGRESS);
desc->handler->shutdown(irq);
/* Caller frees the old guest descriptor block. */
}
#ifdef SUPPORT_MSI_REMAPPING
-/* called with d->event_lock held */
-static void __msi_pirq_eoi(struct hvm_pirq_dpci *pirq_dpci)
-{
- irq_desc_t *desc;
-
- if ( (pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) &&
- (pirq_dpci->flags & HVM_IRQ_DPCI_MACH_MSI) )
- {
- struct pirq *pirq = dpci_pirq(pirq_dpci);
-
- BUG_ON(!local_irq_is_enabled());
- desc = pirq_spin_lock_irq_desc(pirq, NULL);
- if ( !desc )
- return;
-
- desc->status &= ~IRQ_INPROGRESS;
- desc_guest_eoi(desc, pirq);
- }
-}
-
-static int _hvm_dpci_msi_eoi(struct domain *d,
- struct hvm_pirq_dpci *pirq_dpci, void *arg)
-{
- int vector = (long)arg;
-
- if ( (pirq_dpci->flags & HVM_IRQ_DPCI_MACH_MSI) &&
- (pirq_dpci->gmsi.gvec == vector) )
- {
- int dest = pirq_dpci->gmsi.gflags & VMSI_DEST_ID_MASK;
- int dest_mode = !!(pirq_dpci->gmsi.gflags & VMSI_DM_MASK);
-
- if ( vlapic_match_dest(vcpu_vlapic(current), NULL, 0, dest,
- dest_mode) )
- {
- __msi_pirq_eoi(pirq_dpci);
- return 1;
- }
- }
-
- return 0;
-}
-
-void hvm_dpci_msi_eoi(struct domain *d, int vector)
-{
- if ( !iommu_enabled || !d->arch.hvm_domain.irq.dpci )
- return;
-
- spin_lock(&d->event_lock);
- pt_pirq_iterate(d, _hvm_dpci_msi_eoi, (void *)(long)vector);
- spin_unlock(&d->event_lock);
-}
-
static int hvm_pci_msi_assert(struct domain *d,
struct hvm_pirq_dpci *pirq_dpci)
{
else
hvm_pci_intx_assert(d, device, intx);
pirq_dpci->pending++;
-
-#ifdef SUPPORT_MSI_REMAPPING
- if ( pirq_dpci->flags & HVM_IRQ_DPCI_TRANSLATE )
- {
- /* for translated MSI to INTx interrupt, eoi as early as possible */
- __msi_pirq_eoi(pirq_dpci);
- }
-#endif
}
/*